# -*- coding: utf-8 -*-
import re
from time import sleep

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.select import Select


class Web:
    """关键字类"""

    def __init__(self):
        # 代表当前运行用例的浏览器类型
        self.br = 'gc'
        # 运行自动化的驱动对象
        self.driver: webdriver.Chrome = None
        # 关联的字典
        self.relations = {}

    def __find_ele(self, locator: str = ''):
        """
        统一定位的关键字
        :param locator: 元素定位器,同时支持xpath,id
        :return: 定位到的元素,如果没有定位到就返回None
        """
        if locator is None or locator == '':
            return None
        elif locator.startswith('/'):
            # 如果是斜杠开头,我们使用xpath定位
            return self.driver.find_element_by_xpath(locator)
        elif locator.startswith('#') or locator.__contains__('>'):
            # 如果是#开头或者包含>,那么就用css定位
            return self.driver.find_element_by_css_selector(locator)
        else:
            # 默认使用id定位
            return self.driver.find_element_by_id(locator)

    def __get_relations(self, params: str = ''):
        """
        获取关联
        :param params: 需要关联的参数
        :return: 返回关联后的字符串
        """
        if params:
            for key in self.relations:
                params = params.replace('{' + key + '}', str(self.relations.get(key)))

        return params

    def openbrowser(self, browser: str = 'gc'):
        """
        打开浏览器
        :param browser: 选择需要打开的浏览器类型,gc:谷歌(默认),ff:Firefox,ie:IE
        :return:
        """
        if browser == 'gc' or browser == '':
            self.br = 'gc'
            self.driver = webdriver.Chrome()
        elif browser == 'ff':
            self.br = 'ff'
            self.driver = webdriver.Firefox()
        elif browser == 'ie':
            self.br = 'ie'
            self.driver = webdriver.Ie()
        else:
            self.br = 'gc'
            self.driver = webdriver.Chrome()

        # 隐形等待
        self.driver.maximize_window()
        self.driver.implicitly_wait(10)

    def geturl(self, url: str = ''):
        """
        访问网站
        :param url: 需要打开的网站链接
        :return:
        """
        self.sleep('1')
        self.driver.get(url)

    def click(self, locator=None):
        """
        点击元素
        :param locator: 元素定位器,同时支持xpath,css,id
        :return:
        """
        locator = self.__get_relations(locator)
        ele = self.__find_ele(locator)
        ele.click()

    def clickjs(self, locator: str = ''):
        """
        通过js点击元素
        :param locator: 元素定位器,同时支持xpath,css,id
        :return:
        """
        locator = self.__get_relations(locator)
        ele = self.__find_ele(locator)
        ele.click()

    def clear(self, locator: str = ''):
        """
        清空文本框
        :param locator: 元素定位器,同时支持xpath,css,id
        :return:
        """
        ele = self.__find_ele(locator)
        ele.clear()

    def input(self, locator: str = '', value: str = ''):
        """
        文本输入
        :param locator: 元素定位器,同时支持xpath,css,id
        :param value: 需要输入的文本
        :return:
        """
        value = self.__get_relations(value)
        ele = self.__find_ele(locator)
        ele.send_keys(value)

    def intoiframe(self, locator: str = ''):
        """
        进入iframe
        :param locator: 元素定位器,同时支持xpath,css,id
        :return:
        """
        ele = self.__find_ele(locator)
        self.driver.switch_to.frame(ele)

    def outiframe(self):
        """
        退出iframe
        :return:
        """
        self.driver.switch_to.default_content()

    def select(self, locator: str = '', value: str = ''):
        """
        下拉框选择
        :param locator: 元素定位器,同时支持xpath,css,id
        :param value: 选择的值
        :return:
        """
        ele = self.__find_ele(locator)
        select = Select(ele)
        try:
            int(value)
            select.select_by_value(value)
        except:
            select.select_by_visible_text(value)

    def switchwin(self, idx:str = ''):
        """关闭旧窗口,切换到新窗口"""
        handles = self.driver.window_handles
        if idx:
            # 切换到新窗口
            self.driver.switch_to.window(handles[int(idx)])
        else:
            # 关闭旧窗口,只能关闭当前操作的窗口
            self.driver.close()
            # 切换到新窗口
            self.driver.switch_to.window(handles[1])

    def sleep(self, t:str = '0.5'):
        """
        固定等待
        :param t: 需要等待的时间s
        :return:
        """
        t = float(t)
        sleep(t)

    def quit(self):
        """退出浏览器"""
        self.driver.quit()